home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d2 / sysid47.arc / SYSID.ASM < prev    next >
Assembly Source File  |  1989-12-17  |  8KB  |  517 lines

  1. page    75, 110
  2.  
  3. ;--------------------------------------------------------------------
  4. ;
  5. ;    SYSID.ASM
  6. ;
  7. ;    Version 4.7
  8. ;
  9. ;    Two subprograms used by SYSID.PAS:
  10. ;
  11. ;        CPUID        - identifies host CPU and NDP (if
  12. ;                    any)
  13. ;        DISKREAD    - reads absolute sectors from disk
  14. ;
  15. ;    Steve Grant
  16. ;    Long Beach, CA
  17. ;    July 31, 1989
  18. ;
  19. ;--------------------------------------------------------------------
  20.  
  21. .8086
  22. .8087
  23.  
  24.     public    CPUID, DISKREAD
  25.  
  26. CODE    segment    byte
  27.  
  28. ;--------------------------------------------------------------------
  29.  
  30. CPUID    proc    near
  31.  
  32. assume    cs:CODE, ds:DATA, es:nothing, ss:nothing
  33.  
  34. ;    On entry:
  35. ;
  36. ;        BP
  37. ;    SP =>    near return address
  38. ;        offset  of a cpu_info_t record
  39. ;        segment "  "     "        "
  40. ;
  41. ;    On exit, the cpu_info_t record has been filled in as follows:
  42. ;
  43. ;        byte    = CPU type
  44. ;        word    = Machine Status Word
  45. ;        6 bytes    = Global Descriptor Table
  46. ;        6 bytes    = Interrupt Descriptor Table
  47. ;        boolean    = segment register change/interrupt flag
  48. ;        boolean    = 80386 multiplication bug flag
  49. ;        byte    = NDP type
  50. ;        word    = NDP control word
  51.  
  52. mCPU    equ    byte ptr [bx]
  53. mMSW    equ    [bx + 1]
  54. mGDT    equ    [bx + 3]
  55. mIDT    equ    [bx + 9]
  56. mopsize    equ    byte ptr [bx + 15]
  57. mchkint    equ    byte ptr [bx + 16]
  58. mmult    equ    byte ptr [bx + 17]
  59. mNDP    equ    byte ptr [bx + 18]
  60. mNDPCW    equ    [bx + 19]
  61.  
  62. f8088    equ    0
  63. f8086    equ    1
  64. fV20    equ    2
  65. fV30    equ    3
  66. f80188    equ    4
  67. f80186    equ    5
  68. f80286    equ    6
  69. f80386    equ    7
  70. funk    =    0FFH
  71.  
  72. false    equ    0
  73. true    equ    1
  74.  
  75.     push    bp
  76.     mov    bp, sp
  77.     push    ds
  78.     lds    bx, [bp + 4]
  79.     call    cpu
  80.     call    chkint
  81.     call    ndp
  82.     pop    ds
  83.     pop    bp
  84.     ret    4
  85.  
  86. ;--------------------------------------------------------------------
  87.  
  88. cpu    proc near
  89.  
  90. ; interrupt of multi-prefix string instruction
  91.  
  92.     sti
  93.     mov    cx, 0FFFFH
  94.     rep    lods    byte ptr es : [si]
  95.     jcxz    cpu_03
  96.  
  97.     call    piq
  98.     cmp    dx, 4
  99.     jne    cpu_01
  100.  
  101.     mov    mCPU, f8088
  102.     ret
  103.  
  104. cpu_01:
  105.     cmp    dx, 6
  106.     je    cpu_02
  107.  
  108.     jmp    cpu_12
  109.  
  110. cpu_02:
  111.     mov    mCPU, f8086
  112.     ret
  113.  
  114. cpu_03:
  115.  
  116. ; number of bits in displacement register used by shift
  117.  
  118.     mov    al, 0FFH
  119.     mov    cl, 20H
  120.     shl    al, cl
  121.     or    al, al
  122.     jnz    cpu_05
  123.  
  124.     call    piq
  125.     cmp    dx, 4
  126.     jne    cpu_04
  127.  
  128.     mov    mCPU, fV20
  129.     ret
  130.  
  131. cpu_04:
  132.     cmp    dx, 6
  133.     jne    cpu_12
  134.  
  135.     mov    mCPU, fV30
  136.     ret
  137.  
  138. cpu_05:
  139.  
  140. ; order of write/decrement by PUSH SP
  141.  
  142.     push    sp
  143.     pop    ax
  144.     cmp    ax, sp
  145.     je    cpu_07
  146.  
  147.     call    piq
  148.     cmp    dx, 4
  149.     jne    cpu_06
  150.  
  151.     mov    mCPU, f80188
  152.     ret
  153.  
  154. cpu_06:
  155.     cmp    dx, 6
  156.     jne    cpu_12
  157.  
  158.     mov    mCPU, f80186
  159.     ret
  160.  
  161. cpu_07:
  162.  
  163. .286P
  164.  
  165.     smsw    mMSW
  166.     sgdt    mGDT
  167.     sidt    mIDT
  168.  
  169. .8086
  170.  
  171. ; try to alter flag register bits 15-12
  172.  
  173.     pushf
  174.     pop    ax
  175.     mov    cx, ax
  176.     xor    cx, 0F000H
  177.     push    cx
  178.     popf
  179.     pushf
  180.     pop    cx
  181.     cmp    ax, cx
  182.     jne    cpu_08
  183.  
  184.     mov    mCPU, f80286
  185.     ret
  186.  
  187. cpu_08:
  188.     mov    mCPU, f80386
  189.     pushf
  190.     mov    ax, sp
  191.     popf
  192.     inc    ax
  193.     inc    ax
  194.     cmp    ax, sp
  195.     jnz    cpu_09
  196.  
  197.     mov    mopsize, false
  198.     jmp    short cpu_10
  199.  
  200. cpu_09:
  201.     mov    mopsize, true
  202.  
  203. cpu_10:
  204.  
  205. .386P
  206.  
  207.     mov    eax, 0417A000H
  208.     mov    ecx, 81H
  209.     mul    ecx
  210.     cmp    edx, 2
  211.     jne    short cpu_11
  212.  
  213.     cmp    eax, 0FE7A000H
  214.     jne    short cpu_11
  215.  
  216.     mov    mmult, true
  217.     ret
  218.  
  219. cpu_11:
  220.     mov    mmult, false
  221.     ret
  222.  
  223. ; BIX ibm.at/hardware #4663
  224.  
  225. .8086
  226.  
  227. cpu_12:
  228.     mov    mCPU, funk
  229.     ret
  230.  
  231. cpu    endp
  232.  
  233. ;--------------------------------------------------------------------
  234.  
  235. piq    proc near
  236.  
  237. ;     On exit:
  238. ;
  239. ;        DX    = length of prefetch instruction queue
  240. ;
  241. ;    This subroutine uses self-modifying code but can nevertheless
  242. ;    be run repeatedly in the course of the calling program.
  243.  
  244. count    =    7
  245. opincdx    equ    42H            ; inc dx opcode
  246. opnop    equ    90H            ; nop opcode
  247.  
  248.     mov    al, opincdx
  249.     mov    cx, count
  250.     push    cx
  251.     push    cs
  252.     pop    es
  253.     mov    di, offset piq_01 - 1
  254.     push    di
  255.     std
  256.     rep stosb
  257.     mov    al, opnop
  258.     pop    di
  259.     pop    cx
  260.     xor    dx, dx
  261.     cli
  262.     rep stosb
  263.     rept    count
  264.     inc    dx
  265.     endm
  266.  
  267. piq_01:
  268.     sti
  269.     ret
  270.  
  271. piq    endp
  272.  
  273. ;--------------------------------------------------------------------
  274.  
  275. chkint    proc near
  276.  
  277. ; save old INT 01H vector
  278.  
  279.     push    bx
  280.     mov    ax, 3501H
  281.     int    21H
  282.     mov    old_int01_ofs, bx
  283.     mov    old_int01_seg, es
  284.     pop    bx
  285.  
  286. ; redirect INT 01H vector
  287.  
  288.     push    ds
  289.     mov    ax, 2501H
  290.     mov    dx, seg new_int01
  291.     mov    ds, dx
  292.     mov    dx, offset new_int01
  293.     int    21H
  294.     pop    ds
  295.  
  296. ; set TF and change SS -- did we trap on following instruction?
  297.  
  298.     pushf
  299.     pop    ax
  300.     or    ah, 01H            ; set TF
  301.     push    ax
  302.     popf
  303.     push    ss            ; CPU may wait one
  304.                     ; instruction before
  305.                     ; recognizing single step
  306.                     ; interrupt
  307.     pop    ss
  308.  
  309. chkint_01:                ; shouldn't ever trap here
  310.  
  311. ; restore old INT 01H vector
  312.  
  313.     push    ds
  314.     mov    ax, 2501H
  315.     lds    dx, old_int01
  316.     int    21H
  317.     pop    ds
  318.     ret
  319.  
  320. ;--------------------------------------------------------------------
  321.  
  322. new_int01:
  323.  
  324. ;    INT 01H handler (single step)
  325. ;
  326. ;    On entry:
  327. ;
  328. ;    SP =>    IP
  329. ;        CS
  330. ;        flags
  331.  
  332.     sti
  333.     pop    ax            ; IP
  334.     cmp    ax, offset chkint_01
  335.     jb    new_int01_03
  336.     je    new_int01_01
  337.     mov    mchkint, true
  338.     jmp    short new_int01_02
  339.  
  340. new_int01_01:
  341.     mov    mchkint, false
  342.  
  343. new_int01_02:
  344.     pop    cx            ; CS
  345.     pop    dx            ; flags
  346.     and    dh, 0FEH        ; turn off TF
  347.     push    dx            ; flags
  348.     push    cx            ; CS
  349.  
  350. new_int01_03:
  351.     push    ax            ; IP
  352.     iret
  353.  
  354. chkint    endp
  355.  
  356. ;--------------------------------------------------------------------
  357.  
  358. ndp    proc near
  359.  
  360. fnone    equ    0
  361. f8087    equ    1
  362. f80287    equ    2
  363. f80387    equ    3
  364. funk    =    0FFH
  365.  
  366.     mov    ndp_cw, 0000H
  367.     cli
  368.  
  369. ; The next three 80x87 instructions cannot carry the WAIT prefix,
  370. ; because there may not be an 80x87 for which to wait.  The WAIT is
  371. ; therefore emulated with a MOV CX,<value>! LOOP $ combination.
  372.  
  373.                         ;    CPU    NDP
  374.     fnsave    ndp_save            ;     14    221
  375.     mov    cx, (221 - 23 + 16) / 17 + 1    ;      4
  376.     loop    $                ;   17*CX+5
  377.                         ;  17*CX+23
  378.  
  379.     fninit                    ;      8      8
  380.     mov    cx, (8 - 17 + 16) / 17 + 1    ;      4
  381.     loop    $                ;   17*CX+5
  382.                         ;  17*CX+17
  383.  
  384.     fnstcw    ndp_cw                ;     14     24
  385.     mov    cx, (24 - 23 + 16) / 17 + 1    ;      4
  386.     loop    $                ;   17*CX+5
  387.                         ;  17*CX+23
  388.  
  389.     sti
  390.     mov    ax, ndp_cw
  391.     cmp    ax, 0000H
  392.     jne    ndp_01
  393.  
  394.     mov    mNDP, fnone
  395.     ret
  396.  
  397. ndp_01:
  398.     cmp    ax, 03FFH
  399.     jne    ndp_02
  400.  
  401.     mov    mNDP, f8087
  402.     jmp    short ndp_04
  403.  
  404. ndp_02:
  405.     cmp    ax, 037FH
  406.     jne    ndp_05
  407.  
  408.     fld1
  409.     fldz
  410.     fdiv
  411.     fld1
  412.     fchs
  413.     fldz
  414.     fdiv
  415.     fcom
  416.     fstsw    ndp_sw
  417.     mov    ax, ndp_sw
  418.     and    ah, 41H            ; C3, C0
  419.     cmp    ah, 40H            ; ST(0) = ST(1)
  420.     jne    ndp_03
  421.  
  422.     mov    mNDP, f80287
  423.     jmp    short ndp_04
  424.  
  425. ndp_03:
  426.     cmp    ah, 01H            ; ST(0) < ST(1)
  427.     jne    ndp_05
  428.  
  429.     mov    mNDP, f80387
  430.  
  431. ndp_04:
  432.     frstor    ndp_save
  433.     fstcw    mNDPCW
  434.     ret
  435.  
  436. ndp_05:
  437.     mov    mNDP, funk
  438.     ret
  439.  
  440. ndp    endp
  441.  
  442. CPUID    endp
  443.  
  444. ;--------------------------------------------------------------------
  445.  
  446. DISKREAD    proc    near
  447.  
  448. assume cs : CODE, ds : nothing, es : nothing
  449.  
  450. ;    On entry:
  451. ;
  452. ;        BP
  453. ;    SP =>    near return address
  454. ;        offset  of disk buffer
  455. ;        segment "   "     "
  456. ;        number of sectors to read
  457. ;        starting logical sector number
  458. ;        drive number (0=A, 1=B, etc.)
  459. ;
  460. ;    On exit:
  461. ;
  462. ;        AX    = function result
  463. ;            00    - function successful
  464. ;            01..FF    - DOS INT 25H error result
  465.  
  466.     drive            equ    [bp + 12]
  467.     starting_sector        equ    [bp + 10]
  468.     number_of_sectors    equ    [bp + 8]
  469.     buffer            equ    [bp + 4]
  470.  
  471.     push    bp
  472.     mov    bp, sp
  473.     mov    al, drive
  474.     mov    dx, starting_sector
  475.     mov    cx, number_of_sectors
  476.     push    ds
  477.     lds    bx, buffer
  478.     int    25H
  479.     inc    sp            ; fix broken stack
  480.     inc    sp
  481.     pop    ds
  482.     jc    diskread_01
  483.  
  484.     xor    ax, ax
  485.  
  486. diskread_01:
  487.     pop    bp
  488.     ret    10
  489.  
  490. DISKREAD    endp
  491.  
  492. CODE    ends
  493.  
  494. ;--------------------------------------------------------------------
  495.  
  496. DATA    segment    byte
  497.  
  498. ; storage for CPUID
  499.  
  500. ; redirected INT 01H vector
  501.  
  502. old_int01    label    dword
  503. old_int01_ofs    dw    ?
  504. old_int01_seg    dw    ?
  505.  
  506. ; storage for NDPID
  507.  
  508. ; 80x87 control word after initialization, status word after divide by zero
  509.  
  510. ndp_cw        dw    ?
  511. ndp_save    db    94 dup (?)
  512. ndp_sw      dw    ?
  513.  
  514. DATA    ends
  515.  
  516.     end
  517.